package alertOperate

import (
	"context"
	"devops-super/internal/dao"
	"devops-super/internal/model/entity"
	"devops-super/internal/model/mymodel"
	"devops-super/internal/service"
	"github.com/gogf/gf/v2/errors/gerror"
)

type sAlertOperate struct{}

func init() {
	service.RegisterAlertOperate(New())
}

func New() *sAlertOperate {
	return &sAlertOperate{}
}

// GetSceneListByPeople 根据联系人ID获取关联的告警场景列表
func (*sAlertOperate) GetSceneListByPeople(ctx context.Context, peopleId uint64) (res []*mymodel.AlertSceneResponse, err error) {

	// 查询关联的场景
	var sceneIds = make([]int64, 0)
	var alertPeopleToScenes []*entity.AlertPeopleToScene
	err = dao.AlertPeopleToScene.Ctx(ctx).Where(dao.AlertPeopleToScene.Columns().PeopleId, peopleId).
		Scan(&alertPeopleToScenes)
	if err != nil {
		return nil, gerror.Wrap(err, "查询关联场景ID失败")
	}
	for _, itme := range alertPeopleToScenes {
		sceneIds = append(sceneIds, itme.SceneId)
	}
	if len(sceneIds) == 0 {
		return []*mymodel.AlertSceneResponse{}, nil
	}

	// 查询场景详情
	var scenes []*entity.AlertScene
	err = dao.AlertScene.Ctx(ctx).WhereIn(dao.AlertScene.Columns().Id, sceneIds).Scan(&scenes)
	if err != nil {
		return nil, gerror.Wrap(err, "查询场景详情失败")
	}

	// 转换为响应对象
	responses := make([]*mymodel.AlertSceneResponse, len(scenes))
	for i, scene := range scenes {
		responses[i] = &mymodel.AlertSceneResponse{
			Id:         scene.Id,
			Name:       scene.Name,
			Type:       scene.Type,
			DeptId:     scene.DeptId,
			Level:      scene.Level,
			Frequency:  scene.Frequency,
			NoticeType: scene.NoticeType,
			Remark:     scene.Remark,
			CreatedAt:  scene.CreatedAt,
			UpdatedAt:  scene.UpdatedAt,
			BindTo:     scene.BindTo,
			JudgeMark:  scene.JudgeMark,
		}
	}

	return responses, nil
}

// SetPeopleSceneRel 设置联系人关联的告警场景
func (*sAlertOperate) SetPeopleSceneRel(ctx context.Context, peopleId uint64, sceneIds []int64) error {
	// 开启事务
	tx, err := dao.AlertPeopleToScene.DB().Begin(ctx)
	if err != nil {
		return gerror.Wrap(err, "开启事务失败")
	}
	defer func() {
		if err != nil {
			_ = tx.Rollback()
		}
	}()

	// 删除原有关联
	_, err = tx.Ctx(ctx).Model(dao.AlertPeopleToScene.Table()).Where(dao.AlertPeopleToScene.Columns().PeopleId, peopleId).Delete()
	if err != nil {
		return gerror.Wrap(err, "删除原有关联失败")
	}

	// 添加新关联
	if len(sceneIds) > 0 {
		var relations []entity.AlertPeopleToScene
		for _, sceneId := range sceneIds {
			relations = append(relations, entity.AlertPeopleToScene{
				PeopleId: peopleId,
				SceneId:  sceneId,
			})
		}

		_, err = tx.Ctx(ctx).Model(dao.AlertPeopleToScene.Table()).Insert(&relations)
		if err != nil {
			return gerror.Wrap(err, "添加新关联失败")
		}
	}

	// 提交事务
	return tx.Commit()
}

// GetSceneListByDeviceGroup 根据设备分组ID获取关联的告警场景列表
func (*sAlertOperate) GetSceneListByDeviceGroup(ctx context.Context, deviceGroupId uint64) (res []*mymodel.AlertSceneResponse, err error) {

	// 查询关联的场景
	var sceneIds = make([]int64, 0)
	var alertDevicegroupToScenes []*entity.AlertDevicegroupToScene
	err = dao.AlertDevicegroupToScene.Ctx(ctx).Where(dao.AlertDevicegroupToScene.Columns().DeviceGroupId, deviceGroupId).
		Scan(&alertDevicegroupToScenes)
	if err != nil {
		return nil, gerror.Wrap(err, "查询关联场景ID失败")
	}
	for _, itme := range alertDevicegroupToScenes {
		sceneIds = append(sceneIds, itme.SceneId)
	}
	if len(sceneIds) == 0 {
		return []*mymodel.AlertSceneResponse{}, nil
	}

	// 查询场景详情
	var scenes []*entity.AlertScene
	err = dao.AlertScene.Ctx(ctx).WhereIn(dao.AlertScene.Columns().Id, sceneIds).Scan(&scenes)
	if err != nil {
		return nil, gerror.Wrap(err, "查询场景详情失败")
	}

	// 转换为响应对象
	responses := make([]*mymodel.AlertSceneResponse, len(scenes))
	for i, scene := range scenes {
		responses[i] = &mymodel.AlertSceneResponse{
			Id:         scene.Id,
			Name:       scene.Name,
			Type:       scene.Type,
			DeptId:     scene.DeptId,
			Level:      scene.Level,
			Frequency:  scene.Frequency,
			NoticeType: scene.NoticeType,
			Remark:     scene.Remark,
			CreatedAt:  scene.CreatedAt,
			UpdatedAt:  scene.UpdatedAt,
			BindTo:     scene.BindTo,
			JudgeMark:  scene.JudgeMark,
		}
	}

	return responses, nil
}

// SetDeviceGroupSceneRel 设置设备分组关联的告警场景
func (*sAlertOperate) SetDeviceGroupSceneRel(ctx context.Context, deviceGroupId uint64, sceneIds []int64) error {
	// 开启事务
	tx, err := dao.AlertDevicegroupToScene.DB().Begin(ctx)
	if err != nil {
		return gerror.Wrap(err, "开启事务失败")
	}
	defer func() {
		if err != nil {
			_ = tx.Rollback()
		}
	}()

	// 删除原有关联
	_, err = tx.Ctx(ctx).Model(dao.AlertDevicegroupToScene.Table()).Where(dao.AlertDevicegroupToScene.Columns().DeviceGroupId, deviceGroupId).Delete()
	if err != nil {
		return gerror.Wrap(err, "删除原有关联失败")
	}

	// 添加新关联
	if len(sceneIds) > 0 {
		var relations []entity.AlertDevicegroupToScene
		for _, sceneId := range sceneIds {
			relations = append(relations, entity.AlertDevicegroupToScene{
				DeviceGroupId: deviceGroupId,
				SceneId:       sceneId,
			})
		}

		_, err = tx.Ctx(ctx).Model(dao.AlertDevicegroupToScene.Table()).Insert(&relations)
		if err != nil {
			return gerror.Wrap(err, "添加新关联失败")
		}
	}

	// 提交事务
	return tx.Commit()
}

// GetDeviceGroupListByScene 根据场景ID获取关联的设备分组列表
func (*sAlertOperate) GetDeviceGroupListByScene(ctx context.Context, sceneId int64) (res []*mymodel.AppDeviceGroupResponse, err error) {
	// 查询关联的设备分组ID
	var deviceGroupIds = make([]int64, 0)
	var alertDevicegroupToScenes []*entity.AlertDevicegroupToScene
	err = dao.AlertDevicegroupToScene.Ctx(ctx).Where(dao.AlertDevicegroupToScene.Columns().SceneId, sceneId).
		Scan(&alertDevicegroupToScenes)
	if err != nil {
		return nil, gerror.Wrap(err, "查询关联设备分组ID失败")
	}
	for _, itme := range alertDevicegroupToScenes {
		deviceGroupIds = append(deviceGroupIds, int64(itme.DeviceGroupId))
	}
	if len(deviceGroupIds) == 0 {
		return []*mymodel.AppDeviceGroupResponse{}, nil
	}

	// 查询设备分组详情
	var deviceGroups []*entity.AppDeviceGroup
	err = dao.AppDeviceGroup.Ctx(ctx).WhereIn(dao.AppDeviceGroup.Columns().Id, deviceGroupIds).Scan(&deviceGroups)
	if err != nil {
		return nil, gerror.Wrap(err, "查询设备分组详情失败")
	}

	// 转换为响应对象
	responses := make([]*mymodel.AppDeviceGroupResponse, len(deviceGroups))
	for i, group := range deviceGroups {
		responses[i] = &mymodel.AppDeviceGroupResponse{
			Id:       uint64(group.Id),
			GroupKey: group.GroupKey,
			Name:     group.Name,
			Purpose:  group.Purpose,
			Remark:   group.Remark,
			DeptId:   uint64(group.DeptId),
		}
	}

	return responses, nil
}

// SetSceneDeviceGroupRel 设置场景关联的设备分组
func (*sAlertOperate) SetSceneDeviceGroupRel(ctx context.Context, sceneId int64, deviceGroupIds []uint64) error {
	// 开启事务
	tx, err := dao.AlertDevicegroupToScene.DB().Begin(ctx)
	if err != nil {
		return gerror.Wrap(err, "开启事务失败")
	}
	defer func() {
		if err != nil {
			_ = tx.Rollback()
		}
	}()

	// 删除原有关联
	_, err = tx.Ctx(ctx).Model(dao.AlertDevicegroupToScene.Table()).Where(dao.AlertDevicegroupToScene.Columns().SceneId, sceneId).Delete()
	if err != nil {
		return gerror.Wrap(err, "删除原有关联失败")
	}

	// 添加新关联
	if len(deviceGroupIds) > 0 {
		var relations []entity.AlertDevicegroupToScene
		for _, deviceGroupId := range deviceGroupIds {
			relations = append(relations, entity.AlertDevicegroupToScene{
				DeviceGroupId: deviceGroupId,
				SceneId:       sceneId,
			})
		}

		_, err = tx.Ctx(ctx).Model(dao.AlertDevicegroupToScene.Table()).Insert(&relations)
		if err != nil {
			return gerror.Wrap(err, "添加新关联失败")
		}
	}

	// 提交事务
	return tx.Commit()
}

// GetSceneListByDevice 根据deviceNo获取关联的告警场景列表
func (*sAlertOperate) GetSceneListByDevice(ctx context.Context, deviceNo string) (res []*mymodel.AlertSceneResponse, err error) {

	// 查询关联的场景
	var sceneIds = make([]int64, 0)
	var deviceToScenes []*entity.AlertDeviceToScene
	err = dao.AlertDeviceToScene.Ctx(ctx).Where(dao.AlertDeviceToScene.Columns().DeviceNo, deviceNo).
		Scan(&deviceToScenes)
	if err != nil {
		return nil, gerror.Wrap(err, "查询关联场景ID失败")
	}
	for _, deviceToScene := range deviceToScenes {
		sceneIds = append(sceneIds, deviceToScene.SceneId)
	}
	if len(sceneIds) == 0 {
		return []*mymodel.AlertSceneResponse{}, nil
	}
	// 查询场景详情
	var scenes []*entity.AlertScene
	err = dao.AlertScene.Ctx(ctx).WhereIn(dao.AlertScene.Columns().Id, sceneIds).Scan(&scenes)
	if err != nil {
		return nil, gerror.Wrap(err, "查询场景详情失败")
	}

	// 转换为响应对象
	responses := make([]*mymodel.AlertSceneResponse, len(scenes))
	for i, scene := range scenes {
		responses[i] = &mymodel.AlertSceneResponse{
			Id:         scene.Id,
			Name:       scene.Name,
			Type:       scene.Type,
			DeptId:     scene.DeptId,
			Level:      scene.Level,
			Frequency:  scene.Frequency,
			NoticeType: scene.NoticeType,
			Remark:     scene.Remark,
			CreatedAt:  scene.CreatedAt,
			UpdatedAt:  scene.UpdatedAt,
			BindTo:     scene.BindTo,
			JudgeMark:  scene.JudgeMark,
		}
	}

	return responses, nil
}

// SetDeviceSceneRel 设置设备关联的告警场景
func (*sAlertOperate) SetDeviceSceneRel(ctx context.Context, deviceNo string, sceneIds []int64) error {
	// 开启事务
	tx, err := dao.AlertDeviceToScene.DB().Begin(ctx)
	if err != nil {
		return gerror.Wrap(err, "开启事务失败")
	}
	defer func() {
		if err != nil {
			_ = tx.Rollback()
		}
	}()

	// 删除原有关联
	_, err = tx.Ctx(ctx).Model(dao.AlertDeviceToScene.Table()).Where(dao.AlertDeviceToScene.Columns().DeviceNo, deviceNo).Delete()
	if err != nil {
		return gerror.Wrap(err, "删除原有关联失败")
	}

	// 添加新关联
	if len(sceneIds) > 0 {
		var relations []entity.AlertDeviceToScene
		for _, sceneId := range sceneIds {
			relations = append(relations, entity.AlertDeviceToScene{
				DeviceNo: deviceNo,
				SceneId:  sceneId,
			})
		}

		_, err = tx.Ctx(ctx).Model(dao.AlertDeviceToScene.Table()).Insert(&relations)
		if err != nil {
			return gerror.Wrap(err, "添加新关联失败")
		}
	}

	// 提交事务
	return tx.Commit()
}

// GetDeviceListByScene 根据场景ID获取关联的设备列表
func (*sAlertOperate) GetDeviceListByScene(ctx context.Context, sceneId int64) (res []*mymodel.AppDeviceResponse, err error) {
	// 查询关联的设备ID
	var deviceNos = make([]string, 0)
	var alertDeviceToScenes []*entity.AlertDeviceToScene
	err = dao.AlertDeviceToScene.Ctx(ctx).Where(dao.AlertDeviceToScene.Columns().SceneId, sceneId).
		Scan(&alertDeviceToScenes)
	if err != nil {
		return nil, gerror.Wrap(err, "查询关联deviceNos失败")
	}
	for _, alertDeviceToScene := range alertDeviceToScenes {
		deviceNos = append(deviceNos, alertDeviceToScene.DeviceNo)
	}
	if len(deviceNos) == 0 {
		return []*mymodel.AppDeviceResponse{}, nil
	}

	// 查询设备详情
	var devices []*entity.AppDevice
	err = dao.AppDevice.Ctx(ctx).WhereIn(dao.AppDevice.Columns().DeviceNo, deviceNos).Scan(&devices)
	if err != nil {
		return nil, gerror.Wrap(err, "查询设备详情失败")
	}

	// 转换为响应对象
	responses := make([]*mymodel.AppDeviceResponse, len(devices))
	for i, device := range devices {
		responses[i] = &mymodel.AppDeviceResponse{
			Id:        device.Id,
			ProductId: device.ProductId,
			Name:      device.Name,
			DeviceNo:  device.DeviceNo,
			Type:      device.Type,
		}
	}
	return responses, nil
}

// SetSceneDeviceRel 设置场景关联的设备
func (*sAlertOperate) SetSceneDeviceRel(ctx context.Context, sceneId int64, deviceNos []string) error {
	// 开启事务
	tx, err := dao.AlertDeviceToScene.DB().Begin(ctx)
	if err != nil {
		return gerror.Wrap(err, "开启事务失败")
	}
	defer func() {
		if err != nil {
			_ = tx.Rollback()
		}
	}()

	// 删除原有关联
	_, err = tx.Ctx(ctx).Model(dao.AlertDeviceToScene.Table()).Where(dao.AlertDeviceToScene.Columns().SceneId, sceneId).Delete()
	if err != nil {
		return gerror.Wrap(err, "删除原有关联失败")
	}

	// 添加新关联
	if len(deviceNos) > 0 {
		var relations []entity.AlertDeviceToScene
		for _, deviceNo := range deviceNos {
			relations = append(relations, entity.AlertDeviceToScene{
				DeviceNo: deviceNo,
				SceneId:  sceneId,
			})
		}

		_, err = tx.Ctx(ctx).Model(dao.AlertDeviceToScene.Table()).Insert(&relations)
		if err != nil {
			return gerror.Wrap(err, "添加新关联失败")
		}
	}

	// 提交事务
	return tx.Commit()
}

// GetPeopleListByScene 根据场景ID获取关联的联系人列表
func (*sAlertOperate) GetPeopleListByScene(ctx context.Context, sceneId int64) (res []*mymodel.AlertPeopleResponse, err error) {

	// 查询关联的联系人ID
	var peopleIds = make([]uint64, 0)
	var alertPeopleToScenes []*entity.AlertPeopleToScene
	err = dao.AlertPeopleToScene.Ctx(ctx).Where(dao.AlertPeopleToScene.Columns().SceneId, sceneId).
		Scan(&alertPeopleToScenes)
	if err != nil {
		return nil, gerror.Wrap(err, "查询关联联系人ID失败")
	}
	for _, alertPeopleToScene := range alertPeopleToScenes {
		peopleIds = append(peopleIds, alertPeopleToScene.PeopleId)
	}
	if len(peopleIds) == 0 {
		return []*mymodel.AlertPeopleResponse{}, nil
	}

	// 查询联系人详情
	var people []*entity.AlertPeople
	err = dao.AlertPeople.Ctx(ctx).WhereIn(dao.AlertPeople.Columns().Id, peopleIds).Scan(&people)
	if err != nil {
		return nil, gerror.Wrap(err, "查询联系人详情失败")
	}

	// 转换为响应对象
	responses := make([]*mymodel.AlertPeopleResponse, len(people))
	for i, p := range people {
		responses[i] = &mymodel.AlertPeopleResponse{
			Id:               p.Id,
			Name:             p.Name,
			DeptId:           p.DeptId,
			Phone:            p.Phone,
			Email:            p.Email,
			Wechat:           p.Wechat,
			Language:         p.Language,
			Remark:           p.Remark,
			ReceiveFrequency: p.ReceiveFrequency,
			CreatedAt:        p.CreatedAt,
			UpdatedAt:        p.UpdatedAt,
		}
	}

	return responses, nil
}

// SetScenePeopleRel 设置场景关联的联系人
func (*sAlertOperate) SetScenePeopleRel(ctx context.Context, sceneId int64, peopleIds []uint64) error {

	// 开启事务
	tx, err := dao.AlertPeopleToScene.DB().Begin(ctx)
	if err != nil {
		return gerror.Wrap(err, "开启事务失败")
	}
	defer func() {
		if err != nil {
			_ = tx.Rollback()
		}
	}()

	// 删除原有关联
	_, err = tx.Ctx(ctx).Model(dao.AlertPeopleToScene.Table()).Where(dao.AlertPeopleToScene.Columns().SceneId, sceneId).Delete()
	if err != nil {
		return gerror.Wrap(err, "删除原有关联失败")
	}

	// 添加新关联
	if len(peopleIds) > 0 {
		var relations []entity.AlertPeopleToScene
		for _, peopleId := range peopleIds {
			relations = append(relations, entity.AlertPeopleToScene{
				PeopleId: peopleId,
				SceneId:  sceneId,
			})
		}

		_, err = tx.Ctx(ctx).Model(dao.AlertPeopleToScene.Table()).Insert(&relations)
		if err != nil {
			return gerror.Wrap(err, "添加新关联失败")
		}
	}

	// 提交事务
	return tx.Commit()
}
